package com.lin.forum.controller;

import com.lin.forum.common.Result;
import com.lin.forum.common.ResultCodeEnum;
import com.lin.forum.exception.ApplicationException;
import com.lin.forum.model.User;
import com.lin.forum.service.IUserService;
import com.lin.forum.utils.JwtUtils;
import com.lin.forum.utils.SecurityUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@Tag(name = "UserController 用户接口")
@Slf4j
@RequestMapping("/user")
@RestController
public class UserController {
    @Autowired
    private IUserService userServiceImpl;

    /**
     * 用户登录
     * @param username 用户名
     * @param password 密码
     * @return 状态
     * “@RequestParam("userName")” 指定前后端交互过程中，参数的key
     */
    @RequestMapping("/login")
    @Operation(description = "用户登录")
    public Result login(@Parameter(description = "用户名", required = true) @RequestParam("username") String username,
                        @Parameter(description = "密码",required = true) @RequestParam("password") String password){
        if(username==null||password==null||!StringUtils.hasLength(username)||!StringUtils.hasLength(password)){
            log.warn("在UserController，用户登录方法login中，传入的参数为null： username="+username+"password="+password);
            return Result.fail(ResultCodeEnum.ERROR_IS_NULL.getCode(),"账号或密码不能为空");
        }
        String jwt= userServiceImpl.login(username,password);
        if(jwt==null){
            log.warn("在UserController，用户登录方法login中，： jwt="+ jwt);
            return Result.fail("jwt="+jwt);
        }
        log.warn("在UserController，用户登录方法login，登录成功！");
        return Result.success(jwt);
    }

    /**
     * 用户注册
     * @param username 用户名
     * @param nickname 昵称
     * @param password 密码
     * @param passwordRepeat 确认密码
     * @return 状态
     */
    @Operation(description = "用户注册")
    @RequestMapping ("/register")
    public Result register(@Parameter(description = "用户名",required = true) @RequestParam("username") String username,
                           @Parameter(description = "昵称",required = true) @RequestParam("nickname") String nickname ,
                           @Parameter(description = "密码",required = true) @RequestParam("password")  String password,
                           @Parameter(description = "确认密码",required = true) @RequestParam("passwordRepeat") String passwordRepeat){
        //传统方法
        if(username==null||nickname==null||password==null||passwordRepeat==null
                ||!StringUtils.hasLength(username)
                ||!StringUtils.hasLength(nickname)
                ||!StringUtils.hasLength(password)
                ||!StringUtils.hasLength(passwordRepeat)){
            log.warn("在UserController，用户注册方法register中，传入的参数为null：username="+username+"nickname="+nickname+"password="+password+"passwordRepeat="+passwordRepeat);
            return Result.fail(ResultCodeEnum.FAILED_PARAMS_VALIDATE.getCode(),"账号或密码不能为空");
        }
        if(!password.equals(passwordRepeat)){
            log.warn("在UserController，用户注册方法register中，密码与确认密码不相等 参数为：password="+password+"passwordRepeat="+passwordRepeat);
            return Result.fail(ResultCodeEnum.FAILED_TWO_PWD_NOT_SAME.getCode(),ResultCodeEnum.FAILED_TWO_PWD_NOT_SAME.getMessage());
        }
        User user=new User();
        user.setUsername(username);
        user.setNickname(nickname);
        //生成盐
        String saltPassword=SecurityUtils.encrypt(password);
        if (saltPassword.length() != 64) {
            log.warn("在UserController，用户注册方法register中，生成盐，出现参数校验失败，saltPassword.length() != 64");
            return Result.fail(ResultCodeEnum.FAILED_PARAMS_VALIDATE.getCode(),ResultCodeEnum.FAILED_PARAMS_VALIDATE.getMessage());
        }
        String salt = saltPassword.substring(0, 32);     // 前32位
        //加密后的密码
        user.setPassword(saltPassword);
        //设置盐
        user.setSalt(salt);
        System.out.println(user);
        userServiceImpl.createNormalUser(user);
        log.info("在UserController，创建一个普通用户register,新增用户成功  user="+user);
        return Result.success();
    }
    @Parameter(description = "根据id获取用户信息",required = true)
    @RequestMapping("info")
    public Result<User> getUserInfo(HttpServletRequest request,
                                    @Parameter(description = "用户id",required = true) @RequestParam(value = "id",required = false) Integer id){
        User userInfo=null;
        if(id==null){
            //1.id为空，从token中获取当前登录用户信息
            String userToken=request.getHeader("user_token");
            if(userToken==null){
                log.warn("在UserController，getUserInfo方法中，从header中获取信息，userToken:"+userToken);
                //抛出异常
                throw new ApplicationException("token为空");
            }
            //从token中获取用户id
            Integer userId= JwtUtils.getUserIdFromToken(userToken);
            if(userId==null){
                log.warn("在UserController，根据id查询用户信息getUserInfo,参数userId中的参数为空，参数为：id="+id);
                //抛出异常
                throw new ApplicationException(Result.noLogin());
            }
            userInfo=userServiceImpl.selectById(userId);
        }
        else{
            //2.id不为空，从数据库中获取用户信息
            userInfo=userServiceImpl.selectById(id);
        }
        if(userInfo==null){
            log.warn("在UserController，根据id查询用户信息getUserInfo,参数userInfo中的参数为空，参数为：userInfo="+userInfo);
            //抛出异常
            throw new ApplicationException(Result.fail(ResultCodeEnum.FAILED_USER_NOT_EXISTS.getMessage()));
        }
        //成功
        return Result.success(userInfo);
    }
    @Parameter(description = "退出登录")
    @RequestMapping("/logout")
    public  Result logout(HttpServletRequest request){
        log.info("用户退出登录，请求路径：{}", request.getRequestURI());
        return Result.success(ResultCodeEnum.SUCCESS.getCode(),"退出登录成功");
    }
}
